#include<iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iterator>

class Base {
public:
    ~Base(){
        std::cout << "~Base"  << std::endl;
    }
    char operator[](size_t index){
        return '1';
    }

private:
    int i;
};

class Derived : public Base {
public:
    ~Derived(){
        std::cout << "~Derived"  << std::endl;
    }
};


void testDestructor(){
    Base * d = new Derived;
    std::cout << (*d)[0] << std::endl;
    // (*d)[0] = 'b';
    delete d;
}

void testCpp11_for(){
    int v = 53;
    int* a[10];


    for(auto & p : a){
        p = &v;
    }

    int index = 0;
    for(auto * p : a){
        std::cout << index++ << " ";
        if(p != nullptr){
            std::cout << *p;
        }
        std::cout << std::endl;
    }
}

class Slice {
public:
    Slice(const char * data)  : data_(data), size_(strlen(data)) {}
    ~Slice(){}
    
    const char * data() const { return data_;}
    const size_t size() const { return size_;}


private:
    const char * data_; 
    size_t size_;
};



typedef Slice * SlicePtr;

struct SlicePtrCompare {
    bool operator()(const SlicePtr & left, const SlicePtr & right) const{
      const size_t min_len = std::min(left->size(), right->size());
      int r = memcmp(left->data(), right->data(), min_len);
      if (r == 0) {
        if (left->size() < right->size())
          r = -1;
        else if (left->size() > right->size())
          r = +1;
      }
      return r < 0;
    }
};
std::ostream & operator<<(std::ostream & out, const SlicePtr & slice){
    out << slice->data() << ":" << slice->size();
    return out;
}


void std_sort(){
    
    std::vector<SlicePtr> slices = {
        new Slice("hello5"),
        new Slice("hello4"),
        new Slice("hello3"),
        new Slice("hello2"),
        new Slice("hello1"),
    };

    std::sort(slices.begin(), slices.end(), SlicePtrCompare());
    std::copy(slices.begin(), slices.end(), std::ostream_iterator<SlicePtr>(std::cout, " "));
    std::cout << std::endl;
}

int main(){
    testDestructor();
    testCpp11_for();
    std_sort();
}




/*  
    Base(int i=0): i(i) {}
    int getI()const { return i;}


    bool operator==(const Base & left, const Base & right) {
        return left.getI() == right.getI();
    }
    Base s(1), p(2);
    std::cout << "obj.operator==" << (s == p) << std::endl;
    std::cout << "obj.operator==" << (s == 2) << std::endl;
    std::cout << "obj.operator==" << (2 == p) << std::endl;
*/
